/*Hash function 2: Multiplication method*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<time.h>

const int size=100;

struct 
{
	int v;
	char uid[10],pwd[10];
} H[100],T[100];
int n=0;
int a[100];

void dcoll();
void display();
int h(char []);
void collision(int);
void insert(char [],char []);
void load();
void input();
void init();
void authen();
int search(char [],char []);
void frequency();

int main(void)
{
	int ch=1,l=0;
	init();	
	while(ch!=6)
	{
		printf(">>>Menu<<<\n1.Input\n2.Load\n3.Display\n4.Display collisions\n5.Authenticate\n6.Exit\nPlease enter your choice:");
		scanf("%d",&ch);
		switch(ch)
		{
			case 1:input();break;
			case 2:if(l==0){load();l++;}else {init();load();}break;
			case 3:display();break;			
			case 4:dcoll();frequency();break;
			case 5:authen();break;			
			case 6:break;
			default:printf("Invalid input\n");
		}
			
	}
}
int search(char uid[10],char pwd[10])
{
	int k,j,i=0,l;
	k=h(uid);
	j=k-1;
	if(j<0)
		j=99;
	while(l!=j)
	{
		l=k+i;
		if(H[l].v==1)
		{
			if(strcmp(H[l].uid,uid)==0)
				if(strcmp(H[l].pwd,pwd)==0)
					return 1;
				else
					return -2;
		}
		if(H[l].v==0)
			return -1;		
		i++;
	}
	return -1;
}
void authen()
{
	int try=3,rd,ch=1;
	char uid[10],pwd[10];
	while(ch!=0)
	{	
		printf("userid:");
		scanf("%s",&uid[0]);
		printf("password:");
		scanf("%s",&pwd[0]);
		try--;	
		if(try>=0)	
		{
			rd=search(uid,pwd);		
			if(rd==1)
			{
				printf("Login successfull\n");
				return;
			}
			else if(rd==-1)
				printf("Login unsuccessfull:No such userid\nYou have %d tries left\n",try);
			else if(rd==-2)
				printf("Login unsuccessfull:Password mismatch\nYou have %d tries left\n",try);
		}
		else
			printf("Login unsuccessfull:Too many tries, access is forbidden\n");
		printf("Want to continue?(1/0)");
		scanf("%d",&ch);
	}
}
void display()
{
	int i;
	for(i=0;i<100;i++)
		if(H[i].v==1)			
			printf("%d:%s+%s\n",i,H[i].uid,H[i].pwd);
}
int h(char key[10])
{
	return (((int)key)>>(int)key[0])%100;
}
void frequency()
{
	int i,j,f[7];
	for(i=0;i<7;i++)
		f[i]=0;
	for(i=0;i<7;i++)
		for(j=0;j<100;j++)
			if(a[j]==i)
				f[i]++;
	for(i=0;i<7;i++)
		printf("Number of %ds:%d\n",i,f[i]);	
				
}
void collision(int k)
{
	a[k]++;
}
void insert(char uid[10],char pwd[10])
{
	int k,j,i=0,l;
	k=h(uid);
	collision(k);
	j=k-1;
	if(j<0)
		j=99;
	while(l!=j)
	{
		l=k+i;
		if(H[l].v==0)
		{
			strcpy(H[l].uid,uid);
			strcpy(H[l].pwd,pwd);
			H[l].v=1;
			return ;		
		}
		i++;
	}	
	printf("Hash overflow\n");
}
void load()
{
	FILE *f;
	char uid[10],pwd[10];
	int i=0,r;
	f=fopen("pwd3.5.dat","r");
	while(fscanf(f,"%s %s\n",&T[i].uid[0],&T[i].pwd[0])!=EOF)	
		i++;
	n=i;
	fclose(f);	
	for(i=0;i<n;i++)
		insert(T[i].uid,T[i].pwd);
}
void input()
{
	FILE *f;
	char uid[10],pwd[10];	
	int ch=1;
	f=fopen("pwd1.dat","a");
	while(ch!=0)
	{
		printf("userid:");
		scanf("%s",&uid[0]);
		printf("password:");
		scanf("%s",&pwd[0]);
		fprintf(f,"%s %s\n",uid,pwd);
		printf("Want to continue?(1/0)");
		scanf("%d",&ch);
	}
	fclose(f);
}
void init()
{
	int i;
	for(i=0;i<100;i++)
	{
		H[i].v=0;
		a[i]=0;
	}
}
void dcoll()
{
	int i;
	for(i=0;i<100;i++)
		printf("%d:%d\n",i,a[i]);
}
